package com.to8to.autotask.zbinfo;

import static com.to8to.autotask.util.AutoTaskType.SET_JGTIME;
import static com.to8to.autotask.util.DBOperaType.UPDATE;
import static com.to8to.es.db.dao.DBTables.TABLE_ZB;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.elasticsearch.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.to8to.autotask.resulthandler.FailHandler;
import com.to8to.autotask.rpc.SendMsg2ES;
import com.to8to.autotask.util.DBUtil;
import com.to8to.autotask.util.Utils;
import com.to8to.commons.utils.DateUtil;
import com.to8to.es.util.LogUtil;

/**
 * UpdateZBInfoTask.java
 * 作 者：atom.liu
 * 版 本：v2.0
 * 日 期：2014年11月27日
 * 描 述：更新中标部分字段信息任务。每天执行一次。
 */
public class UpdateZBInfoTask implements Runnable
{
    private static final Logger logger = LoggerFactory.getLogger(UpdateZBInfoTask.class);

    /**
     * SQL:查询出符合条件的中标记录
     * jg_time = 0 ：没有竣工时间
     * zxbyh = 0 ：装后保用户
     * 
     * ftime > ? and ftime < ? ：合同结束日期是昨天
     * or
     * z.sqfk_status = 1 and f.puttime != 0:装修公司申请返款
     * 
     * iscostbzj = 1 已交 固定保障金
     */
    private static final String MATCH_ZB_SQL =
        "select * from to8to_jj_smt_zb as z left join to8to_jj_smt_sqfk as f on z.zid = f.zid where z.jg_time = 0 and z.zxbyh = 0 and z.iscostbzj = 1 and ((z.ftime >= '%s' and z.ftime < '%s') or (f.puttime >= %s and f.puttime < %s)) ";

    /**
     * SQL:更新中标数据信息
     * 更新竣工时间为合同结束日期
     * 客服回访时间设置为合同结束日期第二天(也就是执行的当天)
     */
    private static final String UPATE_ZB_SQL =
        "update to8to_jj_smt_zb set jg_time = %s, kftime = %s where zid in (%s) and jg_time = 0 and iscostbzj = 1 and zxbyh = 0";

    @Override
    public void run()
    {
        logger.info("更新中标记录竣工时间和回访时间开始...");

        Connection connect = null;

        List<Integer> zidList = Lists.newArrayList();//因为合同到期要更新的中标id
        List<String> allUpdateZidList = Lists.newArrayList();//全部要更新的zid集合(包含装修公司申请返款的和合同到期的)
        List<String> updateSqls = Lists.newArrayList();//要执行的sql语句
        int fk_time = getKFTime();
        try
        {
            connect = DBUtil.getConnection(false);

            if (DBUtil.execTaskCountsAtToday(connect, SET_JGTIME) != 0)
                return;

            Date yesterday = DateUtil.getYesterday();
            int yesterdayTime = (int) (yesterday.getTime() / 1000);
            String stime = DateUtil.format(yesterday, "yyyy-MM-dd");
            String etime = DateUtil.format(new Date(), "yyyy-MM-dd");

            PreparedStatement stat = connect.prepareStatement(String.format(MATCH_ZB_SQL, stime, etime, yesterdayTime, Utils.getDayTimePoint(0)));
            ResultSet result = stat.executeQuery();
            while (result.next())
            {
                int f_zid = result.getInt("f.zid");
                int zid = result.getInt("z.zid");
                allUpdateZidList.add(String.valueOf(zid));
                //如果装修公司申请返款，则竣工时间设置为申请返款的时间，否则设置为合同结束的日期
                if (f_zid != 0)
                {
                    int f_puttime = result.getInt("f.puttime");
                    updateSqls.add(String.format(UPATE_ZB_SQL, f_puttime, fk_time, f_zid));
                }
                else
                {
                    zidList.add(zid);
                }
            }
            DBUtil.releaseSource(result, stat, null);

            if (zidList.size() == 0 && updateSqls.size() == 0)
            {
                logger.info("本次没有要更新的中标信息");
                return;
            }

            int jg_time = (int) (DateUtil.parse(etime, "yyyy-MM-dd").getTime() / 1000) - 1; //合同到期的将jg_time设置为合同结束那一天的结束
            updateSqls.add(String.format(UPATE_ZB_SQL, jg_time, fk_time, Utils.collect2Str(zidList)));
            DBUtil.refresh2DB(connect, updateSqls, SET_JGTIME, new SendMsg2ES(UPDATE, TABLE_ZB, allUpdateZidList));
            logger.info("更新中标记录竣工时间和回访时间结束...");
        }
        catch (Throwable e)
        {
            logger.error("更新中标信息失败！{} \n {}", e, LogUtil.logStackTrace(e));
            DBUtil.rollback(connect);
            if (e instanceof SQLException)
                FailHandler.handler(UpdateZBInfoTask.class);
        }
        finally
        {
            DBUtil.releaseSource(null, null, connect);
        }
    }

    /**
     * 设置客服回访时间，设置为下午3点 
     */
    private static int getKFTime()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 15);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);

        return (int) (cal.getTimeInMillis() / 1000);
    }
}
